package com.boruan.shengtangfeng.core.utils.weixin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WeChatAuthService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${weixin.open.appid}")
    private String appid;
    @Value("${weixin.open.secret}")
    private String secret;

//请求此地址即跳转到二维码登录界面
    private static final String AUTHORIZATION_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";

    // 获取用户 openid 和access——toke 的 URL
    private static final String ACCESSTOKE_OPENID_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    private static final String REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";

    private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

    private static final String SCOPE = "snsapi_login";

    private static final String APPLET_TOKEN_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

//    public String getAuthorizationUrl() throws UnsupportedEncodingException {
//        String callbackUrl = URLEncoder.encode(baseUrl+"/pc/redirect","utf-8");
//        String url = String.format(AUTHORIZATION_URL,appid,callbackUrl,SCOPE,System.currentTimeMillis());
//        return url;
//    }

    public Map<String, String> getAccessToken(String code) {
        String url = String.format(ACCESSTOKE_OPENID_URL, appid, secret, code); // 微信
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();

        String resp = restTemplate.getForObject(uri, String.class);
        log.error("getAccessToken resp = " + resp);
        if (resp.contains("openid")) {

            JSONObject jsonObject = JSON.parseObject(resp);
            String access_token = jsonObject.getString("access_token");
            String openid = jsonObject.getString("openid");
            String unionid = jsonObject.getString("unionid");
            String refresh_token = jsonObject.getString("refresh_token");

            Map<String, String> res = new HashMap<>();
            res.put("accessToken", access_token);
            res.put("openid", openid);
            res.put("unionid", unionid);
            res.put("refreshToken", refresh_token);

            return res;
        } else {
            throw new RuntimeException("获取token失败，msg = " + resp);
        }
    }

    /**
     * 参数 说明 openid 普通用户的标识，对当前开发者帐号唯一 
     * nickname 普通用户昵称 
     * sex 普通用户性别，1 为男性，2 为女性
     * province 普通用户个人资料填写的省份 
     * city 普通用户个人资料填写的城市 
     * country 国家，如中国为 CN 
     * headimgurl
     * 用户头像，最后一个数值代表正方形头像大小（有 0、46、64、96、132 数值可选，0 代表 640*640 正方形头像），用户没有头像时该项为空
     * privilege 用户特权信息，json 数组，如微信沃卡用户为（chinaunicom） 
     * unionid
     * 用户统一标识。针对一个微信开放平台帐号下的应用，同一用户的 unionid 是唯一的。
     * 
     * @param accessToken
     * @param openId
     * @return
     */
    public JSONObject getUserInfo(String accessToken, String openId) {
        String url = String.format(USER_INFO_URL, accessToken, openId);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();

        String resp = restTemplate.getForObject(uri, String.class);
        log.error("getUserInfo resp = " + resp);
        if (resp.contains("errcode")) {
            throw new RuntimeException("获取用户信息错误，msg = " + resp);
        } else {
            JSONObject jsonObject = JSON.parseObject(resp);
            return jsonObject;
        }
    }

    // 微信的token只有2小时的有效期，过时需要重新获取，所以官方提供了
    // 根据refresh_token 刷新获取token的方法，本项目仅仅是获取用户
    // 信息，并将信息存入库，所以两个小时也已经足够了
    public String refreshToken(String refresh_token) {

        String url = String.format(REFRESH_TOKEN_URL, appid, refresh_token);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();

        ResponseEntity<JSONObject> resp = restTemplate.getForEntity(uri, JSONObject.class);
        JSONObject jsonObject = resp.getBody();

        String access_token = jsonObject.getString("access_token");
        return access_token;
    }
}
